<!DOCTYPE html>
<html>
  <head>
     
    <meta charset="UTF-8">
    <title>Java基础2 - 测开、Java后端最常见、最核心的面试题总结</title>
    <link rel="shortcut icon" href="/static/img/icon.png">
    <link rel="icon" href="/static/img/icon.png" sizes="192x192"/>
    
<link rel="stylesheet" href="/static/kico.css">
<link rel="stylesheet" href="/static/hingle.css">

    
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">

    <meta name="viewport" content="width=device-width, maximum-scale=1, initial-scale=1"/>
    <meta property="og:site_name" content="测开、Java后端最常见、最核心的面试题总结">
    <meta property="og:title" content="Java基础2"/>
    
<meta name="generator" content="Hexo 7.3.0"></head>

  <body>
    <header>
    <div class="head-title">
        <h4>测开、Java后端最常见、最核心的面试题总结</h4>
    </div>
    <div class="head-action">
        <div class="toggle-btn"></div>
        <div class="light-btn"></div>
        <div class="search-btn"></div>
    </div>
    <form class="head-search" method="post">
        <input type="text" name="s" placeholder="搜索什么？">
    </form>
    <nav class="head-menu">
        <a href="/">首页</a>
        
    </nav>
</header>

    <main>
    <div class="wrap min">
        <section class="post-title">
            <h2>Java基础2</h2>
            <div class="post-meta">
                <time class="date">2024.07.25</time>
            
            </div>
        </section>
        <article class="post-content">
        
            <h1><span id="18java中的异常处理体系">18.Java中的异常处理体系</span></h1><p><code>Throwable</code> 是 Java 语言中所有错误和异常的基类。它有两个主要的子类：Error 和 Exception。</p>
<ul>
<li><p>Error 类代表那些严重的错误，这类错误通常是程序无法处理的。比如，OutOfMemoryError 表示内存不足，StackOverflowError 表示栈溢出。这些错误通常与 JVM 的运行状态有关，一旦发生，应用程序通常无法恢复。</p>
</li>
<li><p>Exception 类代表程序可以处理的异常。它分为两大类：编译时异常（Checked Exception）和运行时异常（Runtime Exception）。</p>
<ul>
<li>①、编译时异常（Checked Exception）：这类异常在编译时必须被显式处理（捕获或声明抛出）。<br>如果方法可能抛出某种编译时异常，但没有捕获它（try-catch）或没有在方法声明中用 throws 子句声明它，那么编译将不会通过。例如：IOException、SQLException 等。</li>
<li>②、运行时异常（Runtime Exception）：这类异常在运行时抛出。对于运行时异常，Java 编译器不要求必须处理它们（即不需要捕获也不需要声明抛出）。运行时异常通常是由程序逻辑错误导致的，如 空指针异常、索引越界异常等。</li>
</ul>
</li>
</ul>
<h1><span id="19try-catch-finally-如何使用">19.try-catch-finally 如何使用？</span></h1><ul>
<li><code>try</code>块：用于包含可能会抛出异常的代码。其后可接零个或多个 <code>catch</code> 块，如果没有 <code>catch</code> 块，则必须跟一个 <code>finally</code> 块。</li>
<li><code>catch</code>块：用于捕获并处理<code>try</code>块中抛出的异常。</li>
<li><code>finally</code> 块：无论是否捕获或处理异常，<code>finally</code> 块里的语句都会被执行。当在 <code>try</code> 块或 <code>catch</code> 块中遇到 <code>return</code> 语句时，<code>finally</code> 语句块将在方法返回之前被执行。</li>
</ul>
<h1><span id="20java-io-流了解吗">20.Java IO 流了解吗？</span></h1><p>IO 即 <code>Input/Output</code>，输入和输出。数据输入到计算机内存的过程即输入，反之输出到外部存储（比如数据库，文件）的过程即输出。数据传输过程类似于水流，因此称为 IO 流。IO 流在 Java 中分为输入流和输出流，而根据数据的处理方式又分为字节流和字符流。</p>
<p>Java IO 流的 40 多个类都是从4 个抽象类基类中派生出来的：</p>
<ul>
<li><code>InputStream</code>&#x2F;<code>Reader</code>: 所有的输入流的基类，前者是字节输入流，后者是字符输入流。</li>
<li><code>OutputStream</code>&#x2F;<code>Writer</code>: 所有输出流的基类，前者是字节输出流，后者是字符输出流。</li>
</ul>
<h1><span id="21ix2fo-流为什么要分为字节流和字符流呢">21.I&#x2F;O 流为什么要分为字节流和字符流呢?</span></h1><p>其实字符流是由 Java 虚拟机将字节转换得到的，问题就出在这个过程还比较耗时，并且，如果我们不知道编码类型就很容易出现乱码问题。所以， I&#x2F;O 流就干脆提供了一个直接操作字符的接口，方便我们平时对字符进行流操作。如果音频文件、图片等媒体文件用字节流比较好，如果涉及到字符的话使用字符流比较好。</p>
<h1><span id="22bio-nio-aio-之间的区别">22.BIO、NIO、AIO 之间的区别？</span></h1><p>BIO（Blocking I&#x2F;O）：也就是传统的 IO，基于字节流或字符流进行文件读写，基于 Socket 和 ServerSocket 进行网络通信。采用阻塞式 I&#x2F;O 模型，线程在执行 I&#x2F;O 操作时被阻塞，无法处理其他任务，适用于连接数较少的场景。</p>
<p>NIO（New I&#x2F;O 或 Non-blocking I&#x2F;O）：放在 java.nio 包下，提供了 Channel、Buffer、Selector 等新的抽象。采用非阻塞 I&#x2F;O 模型，线程在等待 I&#x2F;O 时可执行其他任务，通过 Selector 监控多个 Channel 上的事件，适用于连接数多但连接时间短的场景。</p>
<p>AIO（Asynchronous I&#x2F;O）：使用异步 I&#x2F;O 模型，线程发起 I&#x2F;O 请求后立即返回，当 I&#x2F;O 操作完成时通过回调函数通知线程，适用于连接数多且连接时间长的场景。</p>
<h1><span id="23什么是序列化什么是反序列化">23.什么是序列化？什么是反序列化？</span></h1><p>序列化（Serialization）是指将对象转换为字节流的过程，以便能够将该对象保存到文件、数据库，或者进行网络传输。</p>
<p>反序列化（Deserialization）就是将字节流转换回对象的过程，以便构建原始对象。</p>
<h1><span id="24说说有几种序列化方式">24.说说有几种序列化方式？</span></h1><ul>
<li>Java 原生序列化 ：通过<code>ObjectOutputStream</code>和<code>ObjectInputStream</code>实现对象的序列化和反序列化。</li>
<li>Json 序列化：这个可能是我们最常用的序列化方式，Json 序列化的选择很多，一般会使用 jackson 包，通过 ObjectMapper 类来实现Java对象与Json格式之间的转换。</li>
<li>ProtoBuff 序列化：Protocol Buffers是Google开发的一种数据描述语言， 是一种轻便高效的结构化数据存储格式，ProtoBuff 序列化对象可以很大程度上将其压缩，可以大大减少数据传输大小，提高系统性能。</li>
</ul>
<h1><span id="25如果有些字段不想进行序列化怎么办">25.如果有些字段不想进行序列化怎么办？</span></h1><p>对于不想进行序列化的变量，使用 <code>transient</code> 关键字修饰。当对象被序列化时，<code>transient</code>关键字标记的字段会被忽略，不会包含在序列化的数据中。</p>
<p>关于 <code>transient</code> 还有几点注意：</p>
<ul>
<li><code>transient</code> 只能修饰变量，不能修饰类和方法。</li>
<li><code>transient</code> 修饰的变量，在反序列化后变量值将会被置成类型的默认值。例如，如果是修饰 <code>int</code> 类型，那么反序列后结果就是 <code>0</code>。</li>
<li><code>static</code> 变量因为不属于任何对象(Object)，所以无论有没有 <code>transient</code> 关键字修饰，均不会被序列化。</li>
</ul>
<h1><span id="26什么是泛型有什么作用">26.什么是泛型？有什么作用？</span></h1><p>Java 泛型是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制，该机制允许开发人员在编译时检测到非法的类型。泛型的本质是类型参数化，也就是说所操作的数据类型被指定为一个参数。</p>
<p>泛型一般有三种使用方式:<strong>泛型类</strong>、<strong>泛型接口</strong>、<strong>泛型方法</strong>。</p>
<h1><span id="27注解了解吗">27.注解了解吗？</span></h1><p>注解（<code>Annotation</code>） 是 Java5 开始引入的新特性，可以看作是一种特殊的注释，主要用于修饰类、方法或者变量，提供某些信息供程序在编译或者运行时使用。</p>
<p>注解本质是一个继承了<code>Annotation</code> 的特殊接口：</p>
<p>JDK 提供了很多内置的注解（比如 <code>@Override</code>、<code>@Deprecated</code>），同时，我们还可以自定义注解。</p>
<p>注解只有被解析之后才会生效，常见的解析方法有两种：</p>
<ul>
<li><strong>编译期直接扫描</strong>：编译器在编译 Java 代码的时候扫描对应的注解并处理，比如某个方法使用<code>@Override</code> 注解，编译器在编译的时候就会检测当前的方法是否重写了父类对应的方法。</li>
<li><strong>运行期通过反射处理</strong>：像框架中自带的注解(比如 Spring 框架的 <code>@Value</code>、<code>@Component</code>)都是通过反射来进行处理的。</li>
</ul>
<h1><span id="28什么是反射应用原理">28.什么是反射？应用？原理？</span></h1><p>创建一个对象是通过 new 关键字来实现的，比如：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">Person</span> <span class="variable">person</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Person</span>();</span><br></pre></td></tr></table></figure>

<p>Person 类的信息在编译时就确定了，那假如在编译期无法确定类的信息，但又想在运行时获取类的信息、创建类的实例、调用类的方法，这时候就要用到反射。</p>
<p>反射功能主要通过 <code>java.lang.Class</code> 类及 <code>java.lang.reflect</code> 包中的类如 Method, Field, Constructor 等来实现。</p>
<p><strong>反射应用场景</strong></p>
<p>①、Spring 框架就大量使用了反射来动态加载和管理 Bean。</p>
<p>②、Java 的动态代理（Dynamic Proxy）机制就使用了反射来创建代理类。代理类可以在运行时动态处理方法调用，这在实现 AOP 和拦截器时非常有用。</p>
<p>③、JUnit 等测试框架使用反射机制来发现和执行测试方法。反射允许框架扫描类，查找带有特定注解（如 <code>@Test</code>）的方法，并在运行时调用它们。</p>
<p><strong>反射原理</strong></p>
<p>我们都知道 Java 程序的执行分为编译和运行两步，编译之后会生成字节码(.class)文件，JVM 进行类加载的时候，会加载字节码文件，将类型相关的所有信息加载进方法区，反射就是去获取这些信息，然后进行各种操作</p>
<h1><span id="29lambda-表达式了解多少">29.Lambda 表达式了解多少？</span></h1><p>Lambda 表达式主要用于提供一种简洁的方式来表示匿名方法，使 Java 具备了函数式编程的特性。这比以前的匿名内部类要简洁很多。</p>
<p>所谓的函数式编程，就是把函数作为参数传递给方法，或者作为方法的结果返回。</p>
<h1><span id="30stream-流用过吗">30.Stream 流用过吗？</span></h1><p><code>Stream</code> 流，简单来说，就是使用 <code>Stream</code> 对一个包含一个或多个元素的集合做各种操作。这些操作可能是中间操作亦或是终端操作。 终端操作会返回一个结果，而中间操作会返回一个 <code>Stream</code> 流，所以可以进行链式调用。</p>
<p>Stream 流一般用于集合，对集合常见的操作有：<strong>Filter 过滤</strong>、<strong>Sorted 排序</strong>、<strong>Map 转换</strong>、<strong>Count 计数</strong>等。</p>

        </article>
        <section class="post-near">
            <ul>
                
                    <li>上一篇: <a href="/JUC2/">JUC 2</a></li>
                
                
                    <li>下一篇: <a href="/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F1/">操作系统1</a></li>
                
            </ul>
        </section>
        
    
        <section class="post-author">
        
            <figure class="author-avatar">
                <img src="https://sdn.geekzu.org/avatar/d22eb460ecab37fcd7205e6a3c55c228?s=200&r=X&d=" alt="Hingle" />
            </figure>
        
            <div class="author-info">
                <h4>Hingle</h4>
                <p>请在这里设置你的作者信息</p>
            </div>
        </section>
    
    </div>
</main>

    <footer>
    <div class="buttons">
        <a class="to-top" href="#"></a>
    </div>
    <div class="wrap min">
        <section class="widget">
            <div class="row">
                <div class="col-m-4">
                    <h3 class="title-recent">最新文章：</h3>
                    <ul class="post-list"><li class="post-list-item"><a class="post-list-link" href="/%E9%A1%B9%E7%9B%AE/">项目</a></li><li class="post-list-item"><a class="post-list-link" href="/MySQL2/">MySQL2</a></li><li class="post-list-item"><a class="post-list-link" href="/Java17%E6%96%B0%E7%89%B9%E6%80%A7/">Java17新特性</a></li><li class="post-list-item"><a class="post-list-link" href="/Redis2/">Redis2</a></li><li class="post-list-item"><a class="post-list-link" href="/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C2/">计算机网络2</a></li><li class="post-list-item"><a class="post-list-link" href="/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F2/">操作系统2</a></li></ul>
                </div>
            </div>
        </section>
        <section class="sub-footer">
            <p>© 2024 <a href="/">测开、Java后端最常见、最核心的面试题总结</a>. All Rights Reserved. Theme By <a href="https://github.com/Dreamer-Paul/Hingle" target="_blank" rel="nofollow">Hingle</a>.</p>
        </section>
    </div>
</footer>


<script src="/static/kico.js"></script>
<script src="/static/hingle.js"></script>


<script>var hingle = new Paul_Hingle({"copyright":false,"night":false});</script>

  </body>
</html>
